import React from 'react';
import { Space, Button, message } from 'antd';
import { TRDefault } from '@/components/index.js';
import { formatNowTime } from '../helper';
import { Filter, PathTableCalculate } from '../index.js';
import styles from './index.less';

const Calculator = ({ pushHistory }) => {
  // 错误信息
  const [errorInfo, setErrorInfo] = React.useState({
    flag: false,
    msg: '计算错误',
  });
  // 省份选择控制
  const [checked, setChecked] = React.useState(true);
  /** 筛选框的值保存  */
  const [sendPrice, setSendPrice] = React.useState('');
  const [sendAdd, setSendAdd] = React.useState('');
  const [acceptPrice, setAcceptPrice] = React.useState('');
  const [acceptAdd, setAcceptAdd] = React.useState('');

  // 总计输配电价、综合线损率
  const [resultTotal, setResultTotal] = React.useState({
    sendPrice: 0.0,
    totalLoss: 0.0,
  });
  // 两个计算表单的ref
  const filterSendRef = React.createRef('');
  const filterAcceptRef = React.createRef('');
  // 路线table的ref
  const pathTableRef = React.createRef('');

  /**
   * 计算点击
   */
  const calculateClick = () => {
    /** 表单校验  */
    const messages = [
      ...filterSendRef.current.valid().map((msg) => `送出省份的${msg}`),
      ...filterAcceptRef.current.valid().map((msg) => `受端省份的${msg}`),
    ];
    // 有未填写项
    if (messages.length) {
      message.error({
        content: `请填写合法的${messages.join('、')}`,
        className: 'error-msg',
      });
      return;
    }
    let result = {
      sendAdd,
      sendPrice,
      acceptAdd,
      acceptPrice,
      show: true,
      // 待计算
      totalLoss: 0.0,
      // 待计算
      powerSendPrice: 0.0,
      caluclateTime: formatNowTime('HH:mm:ss'),
      paths: pathTableRef.current.getPaths(),
    };
    calculate(result);
  };

  /**
   * 计算输配电价、综合线损率、最终价格
   * @param {Object} history 历史结果对象初始化属性后的对象
   */
  const calculate = (history) => {
    if (checked) {
      let acceptPrice = parseFloat(history.sendPrice);
      history.paths.forEach(({ sendPrice, lossPrice, downPrice }, index) => {
        acceptPrice += parseFloat(sendPrice);
        acceptPrice += parseFloat(downPrice);
        if (index != 0) {
          acceptPrice += parseFloat(lossPrice);
        }
      });
      history.acceptPrice = parseFloat(acceptPrice).toFixed(2);
    } else {
      let sendPrice = parseFloat(history.acceptPrice);
      history.paths.forEach((item, index) => {
        sendPrice -= parseFloat(item.downPrice);
        sendPrice -= parseFloat(item.sendPrice);
        if (index != 0) {
          sendPrice -= parseFloat(item.lossPrice);
        }
      });
      history.sendPrice = parseFloat(sendPrice).toFixed(2);
    }
    history.powerSendPrice = (history.acceptPrice - history.sendPrice).toFixed(2);

    let totalLoss = 1;
    history.paths.forEach(({ loss }) => {
      totalLoss *= 1 - parseFloat(loss);
    });
    history.totalLoss = ((1 - totalLoss) * 100.0).toFixed(2);
    // 更新历史记录
    pushHistory(history);
    // 更新右上角计算结果
    setResultTotal({
      sendPrice: history.powerSendPrice,
      totalLoss: history.totalLoss,
    });
    if (checked) {
      filterAcceptRef.current.updatePrice(history.acceptPrice);
    } else {
      filterSendRef.current.updatePrice(history.sendPrice);
    }
  };

  /**
   * 清空筛选项
   */
  const clearFilters = () => {
    filterAcceptRef.current.clear();
    filterSendRef.current.clear();
    pathTableRef.current.clearImmediate();
    setResultTotal({
      sendPrice: 0.0,
      totalLoss: 0.0,
    });
  };

  /**
   * 筛选项修改监听
   */
  const filterChange = ({ price, province }, type) => {
    if (type == 'send') {
      setSendAdd(province);
      if (checked) {
        setSendPrice(price);
        pathTableRef.current.setCondition({ price, type });
      }
    } else {
      setAcceptAdd(province);
      if (!checked) {
        setAcceptPrice(price);
        pathTableRef.current.setCondition({ price, type });
      }
    }
  };

  /**
   * 筛选项radio切换
   * @param {String} type 计算类型：send、accept
   */
  const filterChooseChange = (type) => {
    pathTableRef.current.setCondition({ price: '', type: checked ? 'send' : 'accept' });
    if (type == 'send' && !checked) {
      setChecked(true);
    } else if (type == 'accept' && checked) {
      setChecked(false);
    }
  };

  /**
   * 展示错误信息
   * @param {*} msg 错误消息
   */
  const showError = (msg) => {
    setErrorInfo({
      flag: true,
      msg,
    });
  };

  return (
    <div className={styles.container}>
      <div className={styles.title}>
        <span>计算器</span>
        {errorInfo.flag ? null : (
          <Button ghost onClick={clearFilters}>
            一键清空
          </Button>
        )}
      </div>
      {errorInfo.flag ? (
        // 错误提示
        <div className={styles.empty}>
          <TRDefault type="emptysm" />
        </div>
      ) : (
        <>
          <Space size="large">
            <Filter
              ref={filterSendRef}
              title="送出省份"
              checked={checked}
              chooseClick={() => filterChooseChange('send')}
              onChange={(info) => filterChange(info, 'send')}
              calculateCB={calculateClick}
            />
            <Filter
              ref={filterAcceptRef}
              title="受端省份"
              checked={!checked}
              chooseClick={() => filterChooseChange('accept')}
              onChange={(info) => filterChange(info, 'accept')}
              calculateCB={calculateClick}
            />
            <div
              className={styles.resultContainer}
              style={{
                display: resultTotal.sendPrice && resultTotal.totalLoss ? 'inline-flex' : 'none',
              }}
            >
              <span className={styles.resultLab}>
                输配电价(元/MWh)：<span className={styles.price}>{resultTotal.sendPrice}</span>
              </span>
              <span className={styles.resultLab}>
                综合线损率(%)：<span className={styles.price}>{resultTotal.totalLoss}</span>
              </span>
            </div>
          </Space>
          {/* 路径选择组件 */}
          <PathTableCalculate ref={pathTableRef} errorFetchData={showError} />
        </>
      )}
    </div>
  );
};

export default Calculator;
